package com.ioftv.controller;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ioftv.common.Result;
import com.ioftv.dto.ImportResultDTO;
import com.ioftv.dto.LabelerTaskPackageExcelDTO;
import com.ioftv.entity.LabelerTaskPackage;
import com.ioftv.listener.LabelerTaskPackageImportListener;
import com.ioftv.service.LabelerTaskPackageService;
import com.ioftv.util.UserContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * 标注员任务包Controller
 */
@Slf4j
@RestController
@RequestMapping("/admin")
public class LabelerTaskPackageController {

    @Autowired
    private LabelerTaskPackageService labelerTaskPackageService;

    /**
     * 1. 分页查询标注员任务包领取及完成情况列表
     * 接口地址: GET /admin/labeler-task-package
     */
    @GetMapping("/labeler-task-package")
    public Result<Page<LabelerTaskPackage>> getLabelerTaskPackageList(
            @RequestParam(defaultValue = "1") Integer currentPage,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,
            @RequestParam(required = false) String labelerName,
            @RequestParam(required = false) String status,
            HttpServletRequest request) {
        // 获取当前用户信息
        Long userId = UserContextUtil.getCurrentUserId(request);
        String username = UserContextUtil.getCurrentUsername(request);
        String role = UserContextUtil.getCurrentUserRole(request);
        
        // 创建分页对象
        Page<LabelerTaskPackage> page = new Page<>(currentPage, pageSize);
        
        // 构建查询条件
        LambdaQueryWrapper<LabelerTaskPackage> queryWrapper = new LambdaQueryWrapper<>();
        
        // 日期范围查询
        if (startDate != null) {
            queryWrapper.ge(LabelerTaskPackage::getReceiveTime, startDate.atStartOfDay());
        }
        if (endDate != null) {
            queryWrapper.le(LabelerTaskPackage::getReceiveTime, endDate.atTime(23, 59, 59));
        }
        
        // 标注员姓名模糊查询
        if (labelerName != null && !labelerName.trim().isEmpty()) {
            queryWrapper.like(LabelerTaskPackage::getLabelerName, labelerName);
        }
        
        // 状态查询
        if (status != null && !status.trim().isEmpty()) {
            queryWrapper.eq(LabelerTaskPackage::getStatus, status);
        }
        
        // 按领取时间倒序排列
        queryWrapper.orderByDesc(LabelerTaskPackage::getReceiveTime);
        
        // 执行分页查询
        Page<LabelerTaskPackage> resultPage = labelerTaskPackageService.page(page, queryWrapper);
        
        return Result.success(resultPage);
    }

    /**
     * 2. 新增标注员任务包记录
     * 接口地址: POST /admin/labeler-task-package
     */
    @PostMapping("/labeler-task-package")
    public Result<Void> addLabelerTaskPackage(@RequestBody LabelerTaskPackage taskPackage, HttpServletRequest request) {
        // 获取当前用户信息
        Long userId = UserContextUtil.getCurrentUserId(request);
        String username = UserContextUtil.getCurrentUsername(request);
        String role = UserContextUtil.getCurrentUserRole(request);
        
        // 参数校验
        if (taskPackage.getLabelerName() == null || taskPackage.getLabelerName().trim().isEmpty()) {
            return Result.error("标注员姓名不能为空");
        }
        
        if (taskPackage.getReceiveTime() == null) {
            return Result.error("领取时间不能为空");
        }
        
        if (taskPackage.getAccount() == null || taskPackage.getAccount().trim().isEmpty()) {
            return Result.error("账号不能为空");
        }
        
        if (taskPackage.getTaskBatch() == null || taskPackage.getTaskBatch().trim().isEmpty()) {
            return Result.error("任务批次不能为空");
        }
        
        if (taskPackage.getPackageId() == null || taskPackage.getPackageId().trim().isEmpty()) {
            return Result.error("提包Id不能为空");
        }
        
        // 设置默认状态
        if (taskPackage.getStatus() == null || taskPackage.getStatus().trim().isEmpty()) {
            taskPackage.setStatus("进行中");
        }
        
        // 保存数据
        boolean success = labelerTaskPackageService.save(taskPackage);
        if (success) {
            return Result.success(null);
        } else {
            return Result.error("新增失败");
        }
    }

    /**
     * 3. 修改标注员任务包记录
     * 接口地址: PUT /admin/labeler-task-package/{id}
     */
    @PutMapping("/labeler-task-package/{id}")
    public Result<Void> updateLabelerTaskPackage(@PathVariable Long id, @RequestBody LabelerTaskPackage taskPackage, HttpServletRequest request) {
        // 获取当前用户信息
        Long userId = UserContextUtil.getCurrentUserId(request);
        String username = UserContextUtil.getCurrentUsername(request);
        String role = UserContextUtil.getCurrentUserRole(request);
        
        // 检查数据是否存在
        LabelerTaskPackage existing = labelerTaskPackageService.getById(id);
        if (existing == null) {
            return Result.error(404, "记录不存在");
        }
        
        // 设置ID
        taskPackage.setId(id);
        
        // 参数校验
        if (taskPackage.getLabelerName() == null || taskPackage.getLabelerName().trim().isEmpty()) {
            return Result.error("标注员姓名不能为空");
        }
        
        if (taskPackage.getReceiveTime() == null) {
            return Result.error("领取时间不能为空");
        }
        
        if (taskPackage.getAccount() == null || taskPackage.getAccount().trim().isEmpty()) {
            return Result.error("账号不能为空");
        }
        
        if (taskPackage.getTaskBatch() == null || taskPackage.getTaskBatch().trim().isEmpty()) {
            return Result.error("任务批次不能为空");
        }
        
        if (taskPackage.getPackageId() == null || taskPackage.getPackageId().trim().isEmpty()) {
            return Result.error("提包Id不能为空");
        }
        
        // 更新数据
        boolean success = labelerTaskPackageService.updateById(taskPackage);
        if (success) {
            return Result.success(null);
        } else {
            return Result.error("修改失败");
        }
    }

    /**
     * 4. 删除标注员任务包记录
     * 接口地址: DELETE /admin/labeler-task-package/{id}
     */
    @DeleteMapping("/labeler-task-package/{id}")
    public Result<Void> deleteLabelerTaskPackage(@PathVariable Long id, HttpServletRequest request) {
        // 获取当前用户信息
        Long userId = UserContextUtil.getCurrentUserId(request);
        String username = UserContextUtil.getCurrentUsername(request);
        String role = UserContextUtil.getCurrentUserRole(request);
        
        // 检查数据是否存在
        LabelerTaskPackage existing = labelerTaskPackageService.getById(id);
        if (existing == null) {
            return Result.error(404, "记录不存在");
        }
        
        // 删除数据
        boolean success = labelerTaskPackageService.removeById(id);
        if (success) {
            return Result.success(null);
        } else {
            return Result.error("删除失败");
        }
    }

    /**
     * 5. 下载标注员任务包导入模板
     * 接口地址: GET /admin/labeler-task-package/template
     */
    @GetMapping("/labeler-task-package/template")
    public void downloadTemplate(HttpServletResponse response, HttpServletRequest request) {
        // 获取当前用户信息
        Long userId = UserContextUtil.getCurrentUserId(request);
        String username = UserContextUtil.getCurrentUsername(request);
        String role = UserContextUtil.getCurrentUserRole(request);
        
        try {
            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("标注员任务包导入模板", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            // 创建空模板（只有表头）
            List<LabelerTaskPackageExcelDTO> templateData = new ArrayList<>();

            // 写入Excel（只生成表头，不含数据）
            EasyExcel.write(response.getOutputStream(), LabelerTaskPackageExcelDTO.class)
                    .sheet("标注员任务包")
                    .doWrite(templateData);

            log.info("下载Excel模板成功");
        } catch (IOException e) {
            log.error("下载Excel模板失败", e);
            throw new RuntimeException("下载模板失败: " + e.getMessage());
        }
    }

    /**
     * 6. 导入标注员任务包数据
     * 接口地址: POST /admin/labeler-task-package/import
     */
    @PostMapping("/labeler-task-package/import")
    public Result<ImportResultDTO> importExcel(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
        // 获取当前用户信息
        Long userId = UserContextUtil.getCurrentUserId(request);
        String username = UserContextUtil.getCurrentUsername(request);
        String role = UserContextUtil.getCurrentUserRole(request);
        
        if (file == null || file.isEmpty()) {
            return Result.error("请选择要导入的文件");
        }

        String fileName = file.getOriginalFilename();
        if (fileName == null || (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls"))) {
            return Result.error("仅支持Excel文件格式（.xlsx或.xls）");
        }

        try {
            log.info("开始导入Excel文件: {}", fileName);

            // 创建导入结果对象
            ImportResultDTO importResult = new ImportResultDTO();

            // 使用监听器模式读取Excel，支持大文件
            LabelerTaskPackageImportListener listener = new LabelerTaskPackageImportListener(labelerTaskPackageService);
            EasyExcel.read(file.getInputStream(), LabelerTaskPackageExcelDTO.class, listener)
                    .sheet()
                    .doRead();

            // 设置导入结果
            importResult.setTotalRows(listener.getTotalRows());
            importResult.setSuccessRows(listener.getSuccessRows());
            importResult.setFailRows(listener.getFailRows());
            importResult.setErrorMessages(listener.getErrorMessages());

            log.info("导入完成: 总行数={}, 成功={}, 失败={}", 
                    importResult.getTotalRows(), 
                    importResult.getSuccessRows(), 
                    importResult.getFailRows());

            return Result.success(importResult);

        } catch (IOException e) {
            log.error("导入Excel文件失败", e);
            return Result.error("导入失败: " + e.getMessage());
        } catch (Exception e) {
            log.error("导入Excel文件异常", e);
            return Result.error("导入异常: " + e.getMessage());
        }
    }

    /**
     * 7. 导出标注员任务包数据
     * 接口地址: GET /admin/labeler-task-package/export
     */
    @GetMapping("/labeler-task-package/export")
    public void exportExcel(
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,
            @RequestParam(required = false) String labelerName,
            @RequestParam(required = false) String status,
            HttpServletResponse response,
            HttpServletRequest request) {
        // 获取当前用户信息
        Long userId = UserContextUtil.getCurrentUserId(request);
        String username = UserContextUtil.getCurrentUsername(request);
        String role = UserContextUtil.getCurrentUserRole(request);
        
        try {
            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("标注员任务包数据_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")), "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            // 构建查询条件
            LambdaQueryWrapper<LabelerTaskPackage> queryWrapper = new LambdaQueryWrapper<>();
            
            // 日期范围查询
            if (startDate != null) {
                queryWrapper.ge(LabelerTaskPackage::getReceiveTime, startDate.atStartOfDay());
            }
            if (endDate != null) {
                queryWrapper.le(LabelerTaskPackage::getReceiveTime, endDate.atTime(23, 59, 59));
            }
            
            // 标注员姓名模糊查询
            if (labelerName != null && !labelerName.trim().isEmpty()) {
                queryWrapper.like(LabelerTaskPackage::getLabelerName, labelerName);
            }
            
            // 状态查询
            if (status != null && !status.trim().isEmpty()) {
                queryWrapper.eq(LabelerTaskPackage::getStatus, status);
            }
            
            // 按领取时间倒序排列
            queryWrapper.orderByDesc(LabelerTaskPackage::getReceiveTime);
            
            // 查询数据
            List<LabelerTaskPackage> taskPackageList = labelerTaskPackageService.list(queryWrapper);
            
            // 转换为Excel DTO
            List<LabelerTaskPackageExcelDTO> excelDataList = new ArrayList<>();
            for (LabelerTaskPackage taskPackage : taskPackageList) {
                LabelerTaskPackageExcelDTO excelDTO = new LabelerTaskPackageExcelDTO();
                excelDTO.setLabelerName(taskPackage.getLabelerName());
                excelDTO.setReceiveTime(taskPackage.getReceiveTime());
                excelDTO.setAccount(taskPackage.getAccount());
                excelDTO.setTaskBatch(taskPackage.getTaskBatch());
                excelDTO.setPackageId(taskPackage.getPackageId());
                excelDTO.setDeliveryTime(taskPackage.getDeliveryTime());
                excelDTO.setDeliveryBoxCount(taskPackage.getDeliveryBoxCount());
                excelDTO.setRepairCount(taskPackage.getRepairCount());
                excelDTO.setFinalBoxCount(taskPackage.getFinalBoxCount());
                excelDTO.setStatus(taskPackage.getStatus());
                excelDataList.add(excelDTO);
            }

            // 写入Excel
            EasyExcel.write(response.getOutputStream(), LabelerTaskPackageExcelDTO.class)
                    .sheet("标注员任务包")
                    .doWrite(excelDataList);

            log.info("导出Excel成功，共导出{}条数据", excelDataList.size());
        } catch (IOException e) {
            log.error("导出Excel失败", e);
            throw new RuntimeException("导出失败: " + e.getMessage());
        }
    }
}